package cn.com.codes.ldapVerification.blh;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;

import org.apache.log4j.Logger;

import cn.com.codes.common.SecurityContextHolderHelp;
import cn.com.codes.framework.app.blh.BusinessBlh;
import cn.com.codes.framework.app.view.View;
import cn.com.codes.framework.common.JsonUtil;
import cn.com.codes.framework.transmission.events.BusiRequestEvent;
import cn.com.codes.ldapConfigInfo.service.LdapConfigInfoService;
import cn.com.codes.ldapVerification.dto.LdapVerificationDto;
import cn.com.codes.ldapVerification.service.LdapVerificationService;
import cn.com.codes.ldapVerification.util.LdapInitUtil;
import cn.com.codes.object.LdapConfigInfo;
import cn.com.codes.object.User;

public class LdapVerificationBlh extends BusinessBlh {

	@SuppressWarnings("unused")
	private static Logger logger = Logger.getLogger(LdapVerificationBlh.class);
	private LdapVerificationService ldapVerificationService;
	private LdapInitUtil ldapInitUtil; 
	private LdapConfigInfoService ldapConfigInfoService;
	

	public View ldapVerificationPage(BusiRequestEvent req){
		return super.getView();
	}
	


	/**
	 * 获取ldap中的所有用户
	 * @param dto 
	 * @param ctx
	 */
	@SuppressWarnings({ "unused", "static-access", "unchecked" })
	public View getLdapAllUserInfo(BusiRequestEvent req) {
		LdapVerificationDto dto = super.getDto(LdapVerificationDto.class, req);
		List<Map<String, Object>> lm=new ArrayList<Map<String, Object>>();
		LdapContext ctx = ldapInitUtil.getLdapDataBase();
		
		try {
			if(ctx != null){
				
				String baseDnSplit = getBaseDnDcDepart();//获取baseDn的dc部分
				String filter = "(&(objectClass=*)(uid=*))";
	            String[] attrPersonArray = { "uid", "userPassword", "cn", "sn", "mail"};
	            SearchControls searchControls = new SearchControls();//搜索控件
	            searchControls.setSearchScope(2);//搜索范围
	            searchControls.setReturningAttributes(attrPersonArray);
	            //1.要搜索的上下文或对象的名称；2.过滤条件，可为null，默认搜索所有信息；3.搜索控件，可为null，使用默认的搜索控件
	            NamingEnumeration<SearchResult> answer = ctx.search(baseDnSplit, filter.toString(),searchControls);
	            while (answer.hasMore()) {
	                SearchResult result = (SearchResult) answer.next();
	                NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
	                Map<String, Object> map = new HashMap<String, Object>();
	                
	                while (attrs.hasMore()) {
	                    Attribute attr = (Attribute) attrs.next();
	                    if("userPassword".equals(attr.getID())){
	                    	Object value = attr.get();
	                        map.put(attr.getID(), new String((byte [])value));
	                    }else{
	                    	map.put(attr.getID(), attr.get());
	                    }
	                }
	                
	                if(map!=null){
                    	lm.add(map);
                    }
	            }
	            
	            if(null != lm && lm.size() > 0){
	            	List<User> userList = new ArrayList<User>();
                	String compamyId =SecurityContextHolderHelp.getCompanyId();
                	for (int i = 0; i < lm.size(); i++) {
                		User user = new User();
	                	user.setLoginName((String)lm.get(i).get("uid"));
	                	user.setEmail((String) lm.get(i).get("mail"));
	                	user.setName((String) lm.get(i).get("cn"));
	                	user.setIsLdap("1");
	                	user.setIsAdmin(0);
	                	user.setInsertDate(new Date()); 
	                	user.setUpdateDate(new Date());
	                	user.setPassword((String) lm.get(i).get("userPassword"));
	                	user.setDelFlag(0);
//	                	user.setCompanyId("1289630248328");
	                	user.setCompanyId(compamyId);
	                	
	                	//查询ldap验证通过后，本地是否有此用户
	                	List<User> users = getLdapAuthFindUser(user);
	                	if(users.size() <= 0){
	                		userList.add(user);
	                	}
					}
                	
                	//ldap所有用户，与本地的ldap用户比较，批量保存
            		ldapVerificationService.batchSaveLdapUserInfo(userList);
                }
	            super.writeResult("success");
			}else{
				super.writeResult("failed");
			}
			
		} catch (NamingException e) {
			e.printStackTrace();
		}
		

		return super.globalAjax();
	}

	@SuppressWarnings("unchecked")
	private String getBaseDnDcDepart() {
		String baseDnSplit = "";
		List<LdapConfigInfo> ldapConfigInfos = ldapConfigInfoService.findBySql("select * from t_ldap_config_info t WHERE t.enable = ? ", LdapConfigInfo.class, "1");
		if(null != ldapConfigInfos && ldapConfigInfos.size() > 0){
			String baseDn = ldapConfigInfos.get(0).getBaseDn();
			String dcStr=baseDn.substring(0, baseDn.indexOf("dc")-1);
		    baseDnSplit = baseDn.substring(dcStr.length()+1, baseDn.length());
		    
		}
		return baseDnSplit;
	}

	/**
	 * @param user 查询用户 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private List<User> getLdapAuthFindUser(User user) {
		List<User> userLs = ldapVerificationService.findBySql(" SELECT * FROM t_user tu WHERE tu.LOGINNAME=? AND tu.is_ldap =? ",
    			User.class,user.getLoginName(),user.getIsLdap());
		return userLs;
	}
	

	@SuppressWarnings({ "unused", "static-access" })
	public View ldapUserAuthentication(BusiRequestEvent req) {//authenticationLdapUserInitConnect
		LdapVerificationDto dto = super.getDto(LdapVerificationDto.class, req);

		LdapContext ctxTDS = ldapInitUtil.getLdapDataBase();
		if(null != ctxTDS){
			searchUserIsNotLdap(dto,ctxTDS);
		}else{
			super.writeResult("failed");
		}
		return super.globalAjax();
	}

	/**
	 * @param 验证用户是否存在
	 * @param pwd
	 * @param pUrl
	 * @param ctxTDS
	 */
	@SuppressWarnings("unchecked")
	private View searchUserIsNotLdap(LdapVerificationDto dto, LdapContext ctxTDS) {
        if(null != ctxTDS){
    		try {
    				String baseDnSplit = getBaseDnDcDepart();//获取baseDn的dc部分
	    			Map<String, Object> resultMap  = new HashMap<String, Object>();
    				//过滤条件
    				String filter = "(&(objectClass=*)(uid="+dto.getUser().getLoginName()+")(userPassword="+dto.getUser().getPassword()+"))";
    	            String[] attrPersonArray = { "uid", "userPassword", "cn", "sn", "mail"};
    	            SearchControls searchControls = new SearchControls();//搜索控件
    	            searchControls.setSearchScope(2);//搜索范围
    	            searchControls.setReturningAttributes(attrPersonArray);
    	            //1.要搜索的上下文或对象的名称；2.过滤条件，可为null，默认搜索所有信息；3.搜索控件，可为null，使用默认的搜索控件
    	            NamingEnumeration<SearchResult> answer = ctxTDS.search(baseDnSplit, filter.toString(),searchControls);
    	            boolean moreFlg = answer.hasMore();
    	            if(moreFlg){
    	            	while (answer.hasMore()) {
        	                SearchResult result = (SearchResult) answer.next();
        	                NamingEnumeration<? extends Attribute> attrs = result.getAttributes().getAll();
        	                Map<String, Object> map = new HashMap<String, Object>();
        	                
        	                while (attrs.hasMore()) {
        	                    Attribute attr = (Attribute) attrs.next();
        	                    if("userPassword".equals(attr.getID())){
        	                    	Object value = attr.get();
        	                        map.put(attr.getID(), new String((byte [])value));
        	                    }else{
        	                    	map.put(attr.getID(), attr.get());
        	                    }
        	                }
        	                
        	                if(map!=null){
        	                	String compamyId =SecurityContextHolderHelp.getCompanyId();
        	                	User user = new User();
        	                	user.setLoginName((String) map.get("uid"));
        	                	user.setEmail((String) map.get("mail"));
        	                	user.setName((String) map.get("cn"));
        	                	user.setIsLdap("1");
        	                	user.setIsAdmin(0);
        	                	user.setInsertDate(new Date()); 
        	                	user.setUpdateDate(new Date());
        	                	user.setPassword((String) map.get("userPassword"));
        	                	user.setDelFlag(0);
        	                	user.setCompanyId(compamyId);
        	                	
        	                	//查询ldap验证通过后，本地是否有此用户
        	                	List<User> users = getLdapAuthFindUser(user);
        	                	if(users.size() <= 0){
        	                		ldapVerificationService.saveLdapUserInfo(user);
        	                	}else{
        	                		User userAuth= users.get(0);
        	                		//当用户通过ldap验证通过，1、本地库已有此用户，2、本地库无此用户，添加该用户，然后加载用户的权限
        	                		ldapVerificationService.ldapAuthUserLoadPrivilege(userAuth);
        	                	}
                            }
        	                
        	            }
    	            	
    	    			resultMap.put("loginItest", "success");
    	    			resultMap.put("HomeUrl", "");
    	    			this.writeResult(JsonUtil.toJson(resultMap));
    	            }else{
    	    			resultMap.put("loginItest", "failed");
    	    			this.writeResult(JsonUtil.toJson(resultMap));
    	            }
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		

        }
		return super.globalAjax();
	}

	public LdapVerificationService getLdapVerificationService() {
		return ldapVerificationService;
	}

	public void setLdapVerificationService(
			LdapVerificationService ldapVerificationService) {
		this.ldapVerificationService = ldapVerificationService;
	}

	public LdapInitUtil getLdapInitUtil() {
		return ldapInitUtil;
	}

	public void setLdapInitUtil(LdapInitUtil ldapInitUtil) {
		this.ldapInitUtil = ldapInitUtil;
	}
	
	public LdapConfigInfoService getLdapConfigInfoService() {
		return ldapConfigInfoService;
	}

	public void setLdapConfigInfoService(LdapConfigInfoService ldapConfigInfoService) {
		this.ldapConfigInfoService = ldapConfigInfoService;
	}

}
